import type { AxiosRequestConfig } from 'axios'
import { API_BASE } from '@/enums'
import { useToken } from '@/hooks'
import { message } from 'ant-design-vue'
import axios from 'axios'
import { handleBlob } from './handle-blob'

const { getToken } = useToken()

const defaultHeaders = {
  'Content-Type': 'application/json;charset=UTF-8',
}

const http = axios.create({
  baseURL: API_BASE,
  timeout: 1000 * 10,
  validateStatus(status) {
    const valid = status === 200
    if (!valid) {
      message.error(`请求失败. status:${status}`)
    }

    return valid
  },
  headers: defaultHeaders,
})

http.interceptors.request.use(
  (conf) => {
    const headers: Record<string, string> = { ...(conf.headers as any) }
    const token = getToken()

    if (token && !headers.token) {
      headers.token = token
    }

    conf.headers = headers as any

    return conf
  },
  err => Promise.reject(err),
)

export const successfulCodes = [0]

// 登录过期跳转到登录页
function jumpToLogin(data: { status?: number }) {
  if (data?.status === 40320) {
    // router.push('/login')
  }
}

http.interceptors.response.use(
  (res) => {
    const { data, config } = res
    const { headers } = config
    const { hideGlobalMessage } = headers!

    if (data instanceof Blob) {
      handleBlob(res as any)
      return res as any
    }
    if (!successfulCodes.includes(data.status)) {
      if (!hideGlobalMessage) {
        message.error(`${data.message || data.msg || ' 处理失败 '}`)
      }
      jumpToLogin(data)
      return Promise.reject(data.message || data.msg)
    }

    return res.data
  },
  (err) => {
    const { data } = err?.response || {}
    jumpToLogin(data)

    return Promise.reject(err)
  },
)

export function get<T = any>(url: string, config?: AxiosRequestConfig): Promise<IResponse<T>> {
  return http.get(url, config)
}

export function post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<IResponse<T>> {
  return http.post(url, data, config)
}

export function put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<IResponse<T>> {
  return http.put(url, data, config)
}

export function del<T = any>(url: string, config?: AxiosRequestConfig): Promise<IResponse<T>> {
  return http.delete(url, config)
}

window.$http = http
export default http
